;;; global.el --- Global bindings used in configuration files -*- lexical-binding: t -*-
;;; Commentary:

;;; Code:
(defun open-user-init-file ()
	"Open the initialization file."
  (interactive)
  (find-file user-init-file))


(defmacro req (&rest specs)
	"Require multiple features at once.

Each of SPECS is a feature specification passed to `require'."
	`(progn
		 ,@(mapcar (lambda (s) `(require ,s))
							 specs)))


(defun require-features (&rest features)
	"Require multiple features at once.

Each of FEATURES is a symbol passed to `require' as its first argument."
	(mapcar (lambda (feat) (require feat))
					features))


(defmacro defile (symbol filename &optional parent-directory docstring)
	"Define a file as a variable.

SYMBOL and DOCSTRING are passed to `defvar' as its parameters of the same name.

FILENAME and PARENT-DIRECTORY are passed to `expand-file-name' to get the
absolute path of the file.  If PARENT-DIRECTORY is nil, it defaults to
`user-emacs-directory'."
	`(defvar ,symbol
		 (expand-file-name ,filename (or ,parent-directory user-emacs-directory))
		 ,docstring))


(defmacro defdir (symbol dirname &optional parent-directory make docstring)
	"Define a directory in the filesystem as a variable.

SYMBOL and DOCSTRING are passed to `defvar' as its parameters of the same name.

DIRNAME and PARENT-DIRECTORY are passed to `expand-file-name' to get the
absolute path of the directory.  If PARENT-DIRECTORY is nil, it defaults to
`user-emacs-directory'.

If MAKE is non-nil, the directory is auto-generated once it does not already
exist."
	`(progn
		 (defile ,symbol ,dirname ,parent-directory ,docstring)
		 (when (and ,make (not (file-exists-p ,symbol)))
			 (make-directory ,symbol))))

;; Directories ;;

(defdir
  user-emacs-config-modules-dir
  "modules" nil t
  "Directory for per-user configuration modules of Emacs.")

(defdir
  user-emacs-config-packages-dir
  "packages" user-emacs-config-modules-dir t
  "Directory for per-user configurations of packages of Emacs.")

(provide 'global)
;;; global.el ends here
